<template>
  <div class="main">
    <el-tabs v-model="activeName" type="card" @tab-change="tabChange">
      <el-tab-pane label="慢SQL明细" name="info">
        <div class="main">
          <div class="slow-sql-header">
            <div class="condition-item">
              <span>开始执行时间</span>
              <el-date-picker
                size="small"
                v-model="infoTimeRange"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
              />
            </div>
            <div class="condition-item">
              <span>执行耗时</span>
              <el-input-number
                style="width: 80px"
                size="small"
                v-model="infoConsumeTimeMin"
                :precision="1"
                :step="0.1"
                :controls="false"
              />
              <span>-</span>
              <el-input-number
                style="width: 80px"
                v-model="infoConsumeTimeMax"
                size="small"
                placeholder="max]"
                :precision="1"
                :step="0.1"
                :controls="false"
              />
            </div>
            <div class="condition-item">
              <span>去除重复SQL</span>
              <el-switch v-model="isFilterRepeated" size="small" />
            </div>
            <div class="condition-item">
              <el-button size="small" @click="getSlowSqlByPageFunc"
                >搜索</el-button
              >
              <el-button style="margin: 0" size="small" @click="resetInfoField"
                >重置</el-button
              >
            </div>
            <div style="position: absolute; right: 0; top: 0">
              <el-button size="small" type="primary" @click="exportSlowSqlInfo"
                >导出慢日志明细</el-button
              >
            </div>
          </div>
          <div class="slow-sql-content">
            <div class="table">
              <el-table :data="infoData" border style="height: 100%">
                <el-table-column
                  prop="start_ts"
                  label="开始执行时间"
                  width="200"
                  align="center"
                />
                <el-table-column
                  prop="sql"
                  label="SQL"
                  align="left"
                  show-overflow-tooltip
                />
                <el-table-column
                  prop="db"
                  label="db"
                  align="center"
                  width="110"
                  show-overflow-tooltip
                />
                <el-table-column
                  prop="ip"
                  label="客户端IP"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="user"
                  label="用户"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="query_time"
                  label="耗时(秒)"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="rows_num"
                  label="返回行数"
                  align="center"
                  width="110"
                />
              </el-table>
            </div>
            <div class="page">
              <el-pagination
                v-model:current-page="infoPage.pageNo"
                v-model:page-size="infoPage.pageSize"
                :page-sizes="[10, 20, 50, 100]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="infoPage.total"
                @current-change="currentPageOrSizeChange(true)"
                @size-change="currentPageOrSizeChange(true)"
              />
            </div>
          </div>
        </div>
      </el-tab-pane>
      <el-tab-pane label="慢SQL统计" name="statistic">
        <div class="main">
          <div class="slow-sql-header">
            <div class="condition-item">
              <span>开始执行时间</span>
              <el-date-picker
                size="small"
                v-model="statisticSlowSqlTimeRange"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
              />
            </div>
            <div class="condition-item">
              <el-button size="small" @click="getStatisticalSlowSqlByPageFunc"
                >搜索</el-button
              >
              <el-button
                style="margin: 0"
                size="small"
                @click="resetStatisticField"
                >重置</el-button
              >
            </div>
          </div>
          <div class="slow-sql-content">
            <div class="table">
              <el-table :data="statisticData" border style="height: 100%">
                <el-table-column
                  prop="sql"
                  label="Sql"
                  align="left"
                  show-overflow-tooltip
                />
                <el-table-column
                  prop="db"
                  label="db"
                  align="center"
                  width="110"
                  show-overflow-tooltip
                />
                <el-table-column
                  prop="query_count"
                  label="执行次数"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="avg_query_time"
                  label="平均耗时(秒)"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="max_query_time"
                  label="最大耗时(秒)"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="avg_rows_num"
                  label="平均返回行数"
                  align="center"
                  width="110"
                />
                <el-table-column
                  prop="max_rows_num"
                  label="最大返回行数"
                  align="center"
                  width="110"
                />
              </el-table>
            </div>
            <div class="page">
              <el-pagination
                v-model:current-page="statisticPage.pageNo"
                v-model:page-size="statisticPage.pageSize"
                :page-sizes="[10, 20, 50, 100]"
                layout="total, sizes, prev, pager, next, jumper"
                :total="statisticPage.total"
                @current-change="currentPageOrSizeChange(false)"
                @size-change="currentPageOrSizeChange(false)"
              />
            </div>
          </div>
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script setup>
import { reactive, ref, onMounted, defineProps } from "vue";
import { getSlowSqlByPage, getStatisticalSlowSqlByPage } from "@/api/index";
import { connectInfoStore } from "../../store/modules/connectInfo";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import ExcelJS from "exceljs";

//属性值
const props = defineProps({
	dbInfo:{
		type:Object,
		default:{},
	},
	databaseInfo:{
		type:Array,
		default:[]
	}
})
const store = {
	info:props.dbInfo,
	databaseInfo: props.databaseInfo
};

const activeName = ref("info");
const infoTimeRange = ref([]);
const infoConsumeTimeMin = ref(10.0);
const infoConsumeTimeMax = ref(undefined);
const isFilterRepeated = ref(false);
const infoData = ref([]);
const infoPage = reactive({
  total: 0,
  pageNo: 1,
  pageSize: 20,
});

let INFO_COLUMN_NAMES = [];

const resetInfoField = () => {
  infoTimeRange.value = getToadyStartAndEndTime();
  infoConsumeTimeMin.value = 10.0;
  infoConsumeTimeMax.value = undefined;
  isFilterRepeated.value = false;
  getSlowSqlByPageFunc();
};

const getToadyStartAndEndTime = () => {
  let start = dayjs().startOf("day").toDate();
  let end = dayjs().endOf("day").toDate();
  return [start, end];
};

const getSlowSqlByPageFunc = () => {
  let dbConfig = store.info;
  let data = {
    startTime: new Date(infoTimeRange.value[0]).getTime(),
    endTime: new Date(infoTimeRange.value[1]).getTime(),
    dbConfig: dbConfig,
    pageParam: infoPage,
    infoConsumeTimeMax: infoConsumeTimeMax.value,
    infoConsumeTimeMin: infoConsumeTimeMin.value,
    isFilterRepeated: isFilterRepeated.value,
  };
  infoData.value.length = 0;
  getSlowSqlByPage(data)
    .then((res) => {
      if (res.code == 200 && res.data && res.data.list) {
        let columns = res.data.list[0];
        INFO_COLUMN_NAMES = columns;
        infoPage.total = res.data.total;
        for (let i = 1; i < res.data.list.length; i++) {
          let data = {};
          let rowData = res.data.list[i];
          for (let j = 0; j < rowData.length; j++) {
            data[columns[j]] = rowData[j];
            if (columns[j] == "query_time") {
              data[columns[j]] = data[columns[j]] / 1000;
            }
          }
          infoData.value.push(data);
        }
      } else {
        ElMessage.error("获取慢SQL明细失败！");
      }
    })
    .catch((e) => {
      console.error(e);
      ElMessage.error("获取慢SQL明细失败！");
    });
};

const statisticSlowSqlTimeRange = ref([]);
const statisticData = ref([]);
const statisticPage = reactive({
  total: 0,
  pageNo: 1,
  pageSize: 20,
});

const resetStatisticField = () => {
  statisticSlowSqlTimeRange.value = [];
};

const getStatisticalSlowSqlByPageFunc = () => {
  let dbConfig = store.info;
  let data = {
    startTime: new Date(statisticSlowSqlTimeRange.value[0]).getTime(),
    endTime: new Date(statisticSlowSqlTimeRange.value[1]).getTime(),
    dbConfig: dbConfig,
    pageParam: statisticPage,
  };
  statisticData.value.length = 0;
  getStatisticalSlowSqlByPage(data)
    .then((res) => {
      if (res.code == 200) {
        let columns = res.data.list[0];
        statisticPage.total = res.data.total;
        for (let i = 1; i < res.data.list.length; i++) {
          let rowData = res.data.list[i];
          let data = {};
          for (let j = 0; j < columns.length; j++) {
            data[columns[j]] = rowData[j];
            if (
              columns[j] == "avg_query_time" ||
              columns[j] == "max_query_time"
            ) {
              data[columns[j]] = data[columns[j]] / 1000;
            }
          }
          statisticData.value.push(data);
        }
      } else {
        ElMessage.error("获取慢Sql统计数据失败：" + res.msg);
      }
    })
    .catch((e) => {
      console.error(e);
      ElMessage.error("获取慢Sql统计数据失败");
    });
};

const tabChange = (name) => {
  if (name == "info") {
    infoPage.pageNo = 1;
    getSlowSqlByPageFunc();
  } else {
    statisticPage.pageNo = 1;
    getStatisticalSlowSqlByPageFunc();
  }
};

const exportSlowSqlInfo = () => {
  const workbook = new ExcelJS.Workbook();
  const workSheet = workbook.addWorksheet("慢SQL明细");
  workSheet.columns = INFO_COLUMN_NAMES.map((item) => {
    return {
      header: item,
      key: item,
      width: 20,
    };
  });
  workSheet.addRows(infoData.value);
  workbook.xlsx.writeBuffer().then((buffer) => {
    const blob = new Blob([buffer], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = "慢SQL明细.xlsx";
    link.click(); // 模拟点击下载文件
  });
};

const currentPageOrSizeChange = (type) => {
  type ? getSlowSqlByPageFunc() : getStatisticalSlowSqlByPageFunc();
};

onMounted(() => {
  infoTimeRange.value = getToadyStartAndEndTime();
  getSlowSqlByPageFunc();
});
</script>
<style lang="less" scoped>
.main {
  height: 100%;
  width: 100%;
  .slow-sql-header {
    height: 36px;
    width: 100%;
    display: flex;
    position: relative;
    & > :not(:last-child) {
      margin-right: 12px;
    }
    .condition-item {
      height: 36px;
      display: flex;
      align-items: flex-start;
    }
    .condition-item > :not(:last-child) {
      display: inline-block;
      margin-right: 12px;
    }
  }
  .slow-sql-content {
    height: calc(100% - 36px);
    width: 100%;
    .table {
      height: calc(100% - 42px);
    }
    .page {
      display: flex;
      flex-direction: row-reverse;
      margin-top: 6px;
      align-items: center;
      height: 36px;
    }
  }
}
</style>
